package com.treasure.service.task.service.impl;

import com.google.common.collect.Lists;
import com.treasure.service.commons.lang.util.BeanUtil;
import com.treasure.service.commons.lang.util.StringUtil;
import com.treasure.service.domain.TaskSchedulerJob;
import com.treasure.service.mapper.TaskSchedulerJobMapper;
import com.treasure.service.task.dto.TaskSchedulerJobDto;
import com.treasure.service.task.service.TaskSchedulerJobService;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/4/10.
 */
@Service("taskSchedulerJobServiceImpl")
public class TaskSchedulerJobServiceImpl implements TaskSchedulerJobService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private TaskSchedulerJobMapper taskSchedulerJobMapper;
    @Autowired
    private QuartzJobFactory auartzJobFactory;
    private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    // SchedulerFactoryBean 创建
    @Autowired
    private Scheduler scheduler;

    public List<TaskSchedulerJobDto> queryALL() {
        List<TaskSchedulerJobDto> listDto = new ArrayList<>();
            List<TaskSchedulerJob> list = taskSchedulerJobMapper.selectAll();
            list.forEach( jobinfo-> {
                try {
                    TaskSchedulerJobDto jobDto = new TaskSchedulerJobDto();
                    BeanUtil.copy(jobinfo,jobDto);
                    JobKey jobKey = new JobKey(jobinfo.getJobName(),jobinfo.getJobGroup());
                    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                    if (triggers!=null && !triggers.isEmpty()){
                        jobDto.setRunPoolCount(triggers.size());
                    }else{
                        jobDto.setRunPoolCount(0);
                    }
                    listDto.add(jobDto);
                } catch (SchedulerException e) {
                    e.printStackTrace();
                }
            });
        return listDto;
    }

    /**
     * 添加任务
     * @param jobDto
     */
    public boolean add(TaskSchedulerJobDto jobDto) {
        if(jobDto.getId()!=null && jobDto.getId()>0 ){
            return  upd(jobDto);
        }
        TaskSchedulerJob job = new TaskSchedulerJob();
        BeanUtil.copy(jobDto,job);
        job.setCreateTime(new Date());
        job.setUpdateTime(new Date());
        job.setStatus("0");
        int i = taskSchedulerJobMapper.insert(job);
        if(i>0)
            return true;
        return false;
    }

    /**
     * 添加任务
     * @param jobDto
     */
    public boolean upd(TaskSchedulerJobDto jobDto){
        TaskSchedulerJob job = taskSchedulerJobMapper.selectByPrimaryKey(jobDto.getId());
        if(job!= null ){
            job.setUpdateTime(new Date());
            if(StringUtil.isNotEmpty(jobDto.getJobGroup()))
                job.setJobGroup(jobDto.getJobGroup());
            if(StringUtil.isNotEmpty(jobDto.getJobName()))
                job.setJobName(jobDto.getJobName());
            if(StringUtil.isNotEmpty(jobDto.getClazz()))
                job.setClazz(jobDto.getClazz());
            if(StringUtil.isNotEmpty(jobDto.getCronExpression()))
                job.setCronExpression(jobDto.getCronExpression());
            int i = taskSchedulerJobMapper.updateByPrimaryKey(job);
            if(i>0)
                return true;
        }

        return false;
    }

    /**
     * 任务
     * @param jobId
     */
    public boolean updUseStatus(Integer jobId) {
        TaskSchedulerJob job = taskSchedulerJobMapper.selectByPrimaryKey(jobId);
        job.setUpdateTime(new Date());
        job.setStatus("1");
       int i=  taskSchedulerJobMapper.updateByPrimaryKey(job);
       if(i>0){
           try {
               auartzJobFactory.createSheduler(job);
               return true;
           } catch (Exception e) {
               job.setStatus("0");
               job.setUpdateTime(new Date());
               taskSchedulerJobMapper.updateByPrimaryKey(job);
               e.printStackTrace();
           }
       }
        return false;
    }

    /**
     * 禁用任务
     * @param jobId
     */
    public boolean updUnUseStatus(Integer jobId) {
        TaskSchedulerJob job =  taskSchedulerJobMapper.selectByPrimaryKey(jobId);
      if(job!= null){
          job.setUpdateTime(new Date());
          job.setStatus("0");
          int i = taskSchedulerJobMapper.updateByPrimaryKey(job);
          if(i>0){
              try {
                  remove(job.getJobName(),job.getJobGroup());
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
        return false;
    }




    /**
     * updStautsToUp任务
     * @param jobName
     * @param jobGroup
     */
    public boolean updStautsToUp(String jobName,String jobGroup) {
        TaskSchedulerJob job = new TaskSchedulerJob();
        job.setJobGroup(jobGroup);
        job.setJobName(jobName);
        List<TaskSchedulerJob> list = taskSchedulerJobMapper.select(job);
        if(list!=null && !list.isEmpty()){
            job = list.get(0);
            try {
                auartzJobFactory.createSheduler(job);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 删除任务
     *
     * @param jobKeyList
     */
    public boolean remove(List<JobKey> jobKeyList){
        try {
            return scheduler.deleteJobs(jobKeyList);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 删除单个任务
     * @param jobName
     * @param jobGroup
     */
    public boolean remove(String jobName,String jobGroup){
        try {
            return  scheduler.deleteJob(new JobKey(jobName,jobGroup));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 暂停定时任务
     * @param jobName
     * @param jobGroup
     */
    public void pause(String jobName, String jobGroup){
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        try {
            if (checkExists(jobName, jobGroup)) {
                scheduler.pauseTrigger(triggerKey);
                logger.info("===> Pause success, triggerKey:{}", triggerKey);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 停用所有任务
    public boolean disableAll(){
        try {
            scheduler.pauseAll();
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 重新开始任务
     * @param jobName
     * @param jobGroup
     */
    public void resume(String jobName, String jobGroup){
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);

        try {
            if (checkExists(jobName, jobGroup)) {
                scheduler.resumeTrigger(triggerKey);
                logger.info("===> Resume success, triggerKey:{}", triggerKey);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 启用所有任务
    public boolean enableAll(){
        try {
            scheduler.resumeAll();
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 立即触发任务
    public boolean triggerNow(JobKey jobKey, JobDataMap jobDataMap){
        try {
            scheduler.triggerJob(jobKey,jobDataMap);
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 验证是否存在
     * @param jobName
     * @param jobGroup
     * @throws SchedulerException
     * 2016年10月8日下午5:30:43
     */
    public boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        return scheduler.checkExists(triggerKey);
    }

    /**
     * 所有已初始化任务列表
     * 2016年10月9日上午11:16:59
     */
    public List<TaskSchedulerJobDto> list(){
        List<TaskSchedulerJobDto> list = new ArrayList<>();
        try {
            for(String groupJob: scheduler.getJobGroupNames()){
                for(JobKey jobKey: scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(groupJob))){
                    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                    for (Trigger trigger: triggers) {
                        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                        String cronExpression = "", createTime = "";
                        if (trigger instanceof CronTrigger) {
                            CronTrigger cronTrigger = (CronTrigger) trigger;
                            cronExpression = cronTrigger.getCronExpression();
                            createTime = cronTrigger.getDescription();
                        }
                        TaskSchedulerJobDto info = new TaskSchedulerJobDto();
                        info.setJobName(jobKey.getName());
                        info.setJobGroup(jobKey.getGroup());
                        info.setDescription(jobDetail.getDescription());
                        info.setJobStatus(triggerState.name());
                        info.setCronExpression(cronExpression);
                        try{
                            if(StringUtil.isNotEmpty(createTime))
                            info.setRunStartTime(df.parse(createTime));
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                       // info.setCreateTime(createTime);
                        list.add(info);
                    }
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 根据key 获取jobDetail
     * @param jobKey
     * @return
     */
    @Transactional(readOnly = true)
    public JobDetail getJobDetailByKey(JobKey jobKey){
        JobDetail jd = null;
        try {
            jd = scheduler.getJobDetail(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jd;
    }

    /**
     * 根据key 获取job trigger
     * @param jobKey
     * @return
     */
    public List<Trigger> getTriggerByKey(JobKey jobKey){
        List<Trigger> triggerList = Lists.newArrayList();
        try {
            triggerList = (List<Trigger>)scheduler.getTriggersOfJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return triggerList;
    }

    public void initScheduleJob(){
        auartzJobFactory.initScheduleJob();
    }

}
